#include <interfaces/SocketEventMonitor.h>
#include "../TcpAcceptor.h"

#include <arpa/inet.h>

// TODO: Move this to central controlled header file
#include <string.h>

namespace Greatewall
{
    namespace Network
    {

        bool
        TcpAcceptor::initTcpAcceptor(short port, std::string netif, int backlog)
        {
            if (_inited)
            {
                // TODO: Error handling
                return false;
            }

            if (port <= 0)
            {
                // TODO: Error handling
                return false;
            }

            if (!initTcpSock(port, backlog, netif))
            {
                // TODO: Error handling
                return false;
            }

            _sock_event_monitor.registerSocket(this, SocketEventMonitor::IN);

            return true;
        }

        void
        TcpAcceptor::handleInbound()
        {
            // buf and size will be ignored here.
            sockaddr_in incoming;
            memset(&incoming, 0, sizeof(incoming));

            socklen_t   incoming_socklen = 0;

            SysSockHandler hdl = accept(_hdl, (sockaddr*)&incoming, &incoming_socklen);

            if (hdl == -1)
            {
                // TODO: Error handling
                return;
            }

            std::string host = inet_ntoa(*(in_addr*)&incoming.sin_addr.s_addr);
            int port = ntohs(incoming.sin_port);

            SystemSocket* sock = createClientHandler(hdl, host, port);

            if (sock == 0)
            {
                // TODO: Error handling
                return;
            }

            _sock_event_monitor.registerSocket(sock, SocketEventMonitor::IN);
        }
    }
}
